package auto.app.service.impl;

import auto.app.controller.from.InterfaceAddFrom;
import auto.app.controller.from.InterfaceDeleteFrom;
import auto.app.controller.from.InterfacePageFrom;
import auto.app.controller.from.InterfaceUpdateFrom;
import auto.app.controller.info.InterfaceInfo;
import auto.app.controller.info.InterfacePageInfo;
import auto.app.dao.TestingEnvironmentDao;
import auto.app.exetion.MainExection;
import auto.app.model.CaseInterface;
import auto.app.model.Interface;
import auto.app.dao.InterfaceDao;
import auto.app.model.TestingEnvironment;
import auto.app.service.CaseService;
import auto.app.service.InterfaceService;
import auto.app.util.CommonUtil;
import auto.app.util.ObjectNull;
import auto.app.util.UserGetAccount;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

import static auto.app.exetion.MainExetionMessage.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 杨森
 * @since 2022-07-09
 */
@Service
public class InterfaceServiceImpl extends ServiceImpl<InterfaceDao, Interface> implements InterfaceService {

    @Autowired
    private TestingEnvironmentDao testingEnvironmentDao;

    @Autowired
    private CaseService caseService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addInterface(InterfaceAddFrom interfaceAddFrom) throws MainExection {
        //校验测试环境是否存在
        TestingEnvironment testingEnvironment = testingEnvironmentDao.selectById(interfaceAddFrom.getTestingEnvironment());
        if (testingEnvironment == null)
            throw new MainExection(TESTINGENVIRONMENT.getCode(), TESTINGENVIRONMENT.getMsg());
        //对新增接口进行校验
        Boolean aBoolean = chickInterface(interfaceAddFrom);
        if (aBoolean) {
            //插入接口数据
            Interface anInterface = CommonUtil.copyOne(interfaceAddFrom, Interface.class);
            anInterface.setCreateTime(LocalDateTime.now());
            anInterface.setCreateBy(UserGetAccount.getAccountId());
            anInterface.setCreateName(UserGetAccount.getAccountName());
            //新增数据
            boolean save = this.save(anInterface);
            return save;
        } else {
            throw new MainExection(INTERFACEADDERROR.getCode(), INTERFACEADDERROR.getMsg());
        }
    }

    private Boolean chickInterface(InterfaceAddFrom interfaceAddFrom) {
        LambdaQueryWrapper<Interface> lambdaQueryWrapper = new LambdaQueryWrapper<Interface>()
                //接口名称查询
                .eq(Interface::getInterfaceName, interfaceAddFrom.getInterfaceName())
                //参数类型查询
                .eq(Interface::getParameterType, interfaceAddFrom.getParameterType())
                //请求方式查询
                .eq(Interface::getRequsetMethod, interfaceAddFrom.getRequsetMethod())
                //请求路径
                .eq(Interface::getRequestPath, interfaceAddFrom.getRequestPath())
                //测试环境ID
                .eq(Interface::getTestingEnvironment, interfaceAddFrom.getTestingEnvironment());
        List<Interface> interfaces = baseMapper.selectList(lambdaQueryWrapper);
        //存在相同数据
        if (ObjectUtil.isNotNull(interfaces) && interfaces.size() > 0) {
            return false;
        } else {
            return true;
        }

    }

    @Override
    public InterfacePageInfo listInterface(InterfacePageFrom interfacePageFrom) {
        QueryWrapper<InterfaceInfo> lambdaQueryWrapper = new QueryWrapper<InterfaceInfo>()
                //测试环境查询
                .like(ObjectNull.isNotNull(interfacePageFrom.getApiname()), "te.apiname", interfacePageFrom.getApiname())
                //请求类型查询
                .eq(ObjectNull.isNotNull(interfacePageFrom.getParameterType()), "parameter_type", interfacePageFrom.getParameterType())
                //请求方式查询
                .eq(ObjectNull.isNotNull(interfacePageFrom.getRequsetMethod()), "requset_method", interfacePageFrom.getRequsetMethod())
                //接口名称查询
                .like(ObjectNull.isNotNull(interfacePageFrom.getInterfaceName()), "Interface_name", interfacePageFrom.getInterfaceName())
                //请求路径查询
                .eq(ObjectNull.isNotNull(interfacePageFrom.getRequestPath()), "request_path", interfacePageFrom.getRequestPath())
                .eq("it.Is_Deleted", 0)
                //排序倒序
                .orderByDesc("it.create_time");
        Page<InterfaceInfo> interfaceInfoPage = baseMapper.listAll(interfacePageFrom, lambdaQueryWrapper);
        //获取数据
        return CommonUtil.copyOne(interfaceInfoPage, InterfacePageInfo.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateInterface(InterfaceUpdateFrom interfaceUpdateFrom) throws MainExection {
        //先查询该主键id下的数据是否存在
        Interface anInterface = baseMapper.selectById(interfaceUpdateFrom.getInterfaceId());
        if (anInterface == null) throw new MainExection(INTERFACEERROR.getCode(), INTERFACEERROR.getMsg());
        //进行参数校验
        Boolean aBoolean = chickInterfaceUpdate(interfaceUpdateFrom);
        if (aBoolean) {
            //如果存在直接更改
            Interface anInterface1 = CommonUtil.copyOne(interfaceUpdateFrom, Interface.class);
            anInterface1.setLastupdateTime(LocalDateTime.now());
            anInterface1.setLastupdateBy(UserGetAccount.getAccountId());
            anInterface1.setLastupdateName(UserGetAccount.getAccountName());
            boolean b = this.updateById(anInterface1);
            return b;
        } else {
            throw new MainExection(INTERFACEADDERROR.getCode(), INTERFACEADDERROR.getMsg());
        }
    }

    private Boolean chickInterfaceUpdate(InterfaceUpdateFrom interfaceUpdateFrom) {
        LambdaQueryWrapper<Interface> lambdaQueryWrapper = new LambdaQueryWrapper<Interface>()
                //接口名称查询
                .eq(Interface::getInterfaceName, interfaceUpdateFrom.getInterfaceName())
                //参数类型查询
                .eq(Interface::getParameterType, interfaceUpdateFrom.getParameterType())
                //请求方式查询
                .eq(Interface::getRequsetMethod, interfaceUpdateFrom.getRequsetMethod())
                //请求路径
                .eq(Interface::getRequestPath, interfaceUpdateFrom.getRequestPath())
                //测试环境ID
                .eq(Interface::getTestingEnvironment, interfaceUpdateFrom.getTestingEnvironment())
                //主键ID
                .ne(Interface::getInterfaceId, interfaceUpdateFrom.getInterfaceId());
        List<Interface> interfaces = baseMapper.selectList(lambdaQueryWrapper);
        //存在相同数据
        if (ObjectUtil.isNotNull(interfaces) && interfaces.size() > 0) {
            return false;
        } else {
            return true;
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteids(InterfaceDeleteFrom interfaceDeleteFrom) throws MainExection {
        //先查询集合中的id是否存在
        List<Integer> ids = interfaceDeleteFrom.getIds();
        ArrayList<Integer> integerArrayList = new ArrayList<>();
        //对删除接口进行优化 循环删除影响速度
        List<Interface> interfaceList = this.list();
        Map<Integer, Interface> collect = interfaceList.stream().collect(Collectors.toMap(Interface::getInterfaceId, Function.identity()));
        //获取所有测试用例的数据
        Map<Integer, List<CaseInterface>> CaseInterfaceListMap = caseService.list().stream().collect(Collectors.groupingBy(CaseInterface::getInterfaceId));
        for (Integer id : ids) {
            Interface anInterface = collect.get(id);
            if (ObjectUtil.isNotNull(anInterface)) {
                List<CaseInterface> caseInterfaces = CaseInterfaceListMap.get(anInterface.getInterfaceId());
                if (ObjectNull.isNotNull(caseInterfaces) && caseInterfaces.size() > 0) {
                    throw new MainExection(DELETEINTERFACECASEERROR.getCode(), DELETEINTERFACECASEERROR.getMsg() + ":" + caseInterfaces.get(0).getCaseName());
                }
            }
            integerArrayList.add(id);
        }
        boolean b = this.removeByIds(integerArrayList);
        return b;
    }
}
